﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;
using Bestcode.MathParser;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace Tubes4_Metnum.Machine
{
    public class Romberg
    {
        public MathParser parser;
        public String[] ColumnHeader;
        public String[] ColumnName;
        public double[][] table;
        public double[] a;
        public double[] b;
        public double[] n; // n = 2^k
        public double[] k;
        public int nVar;
        public double result;

        public Romberg()
        {
            parser = new MathParser();
            this.a = new double[2];
            this.b = new double[2];
            this.n = new double[2];
            this.k = new double[2];
        }

        public double integral(double a, double b, int n, String expression)
        {
            parser.Expression = expression;
            this.a[0] = a;
            this.b[0] = b;
            this.n[0] = n;
            this.k[0] = Math.Log(this.n[0], 2.0);
            this.nVar = 1;

            return integral();
        }

        private double integral()
        {
            int tempk = (int)this.k[0];
            table = new double[tempk + 1][];
            double selang = 0;
            double value = 0;
            double a = this.a[0];
            double b = this.b[0];
            
            this.ColumnHeader = new String[tempk + 1];
            this.ColumnName = new String[tempk + 1];

            for (int k = 0; k < table.Length; k++)
            {
                table[k] = new double[table.Length];

                // Pembuatan nilai A
                selang = ((b - a) / Math.Pow(2.0, k));
                parser.X = a;
                value = (double)parser.Value;
                for (double tempX = a + selang; tempX < b; tempX += selang)
                {
                    parser.X = tempX;
                    value += (double)parser.Value * 2.0;
                }
                parser.X = b;
                value += (double)parser.Value;
                table[k][0] = selang * value / 2.0;

                // Pembuatan nilai B dan seterusnya
                for (int i = 1; i <= k; i++)
                {
                    table[k][i] = ((Math.Pow(4.0, i) * table[k][i - 1]) - table[k - 1][i - 1]) / (Math.Pow(4.0, i) - 1.0);
                }

                this.ColumnHeader[k] = "O(h" + (2.0 * (k + 1.0)) + ")";
                this.ColumnName[k] = "ColumnOh" + (2.0 * (k + 1.0)).ToString();
            }

            result = table[tempk][tempk];
            return result;
        }

        public void PrintData()
        {
            Console.WriteLine("a: " + a[0]);
            Console.WriteLine("b: " + b[0]);
            Console.WriteLine("n: " + n[0]);
            Console.WriteLine("k: " + k[0]);
            Console.WriteLine("hasil: " + result);
        }

        public void PrintTable()
        {
            for (int i = 0; i < table.Length; i++)
            {
                Console.WriteLine("Table baris ke-" + (i + 1));
                for (int j = 0; j <= i; j++)
                {
                    Console.Write(table[i][j]);
                    if (j != i)
                        Console.Write(" , ");
                }
                Console.WriteLine("");
            }
        }

        public void saveFile(string filePath)
        {
            Document document = new Document();
            try
            {
                string ext = filePath.Substring(filePath.Length - 4, 4);
                if (ext.CompareTo(".pdf") != 0) filePath += ".pdf";
                PdfWriter.GetInstance(document, new FileStream(filePath, FileMode.Create));
                document.Open();

                document.Add(new Paragraph("Metode Romberg"));

                PdfPTable ptable;
                PdfPCell pcell;
                if (this.nVar == 1)
                {
                    document.Add(new Paragraph("a = " + this.a[0] + "; b = " + this.b[0] + "; n = " + this.n[0] + "; k = " + this.k[0]));
                    ptable = new PdfPTable(table.Length);
                    iTextSharp.text.Font arial7 = FontFactory.GetFont("ARIAL", 7);
                    for (int i = 0; i < ColumnHeader.Length; i++)
                    {
                        pcell = new PdfPCell(new Phrase(new Chunk(this.ColumnHeader[i], arial7)));
                        ptable.AddCell(pcell);
                    }

                    for (int i = 0; i < table.Length; i++)
                    {
                        int j = 0;
                        for (; j <= i; j++)
                        {
                            pcell = new PdfPCell(new Phrase(new Chunk(this.table[i][j].ToString(), arial7)));
                            ptable.AddCell(pcell);
                        }
                        for (; j < table.Length; j++)
                        {
                            pcell = new PdfPCell(new Phrase(new Chunk("-", arial7)));
                            ptable.AddCell(pcell);
                        }
                    }
                }
                else
                {
                    document.Add(new Paragraph("ax = " + this.a[0] + "; bx = " + this.b[0] + "; nx = " + this.n[0] + "; kx = " + this.k[0]));
                    document.Add(new Paragraph("ay = " + this.a[1] + "; by = " + this.b[1] + "; ny = " + this.n[1] + "; ky = " + this.k[1]));

                    ptable = new PdfPTable(table.Length);
                    iTextSharp.text.Font arial7 = FontFactory.GetFont("ARIAL", 7);
                    for (int i = 0; i < ColumnHeader.Length; i++)
                    {
                        pcell = new PdfPCell(new Phrase(new Chunk(this.ColumnHeader[i], arial7)));
                        ptable.AddCell(pcell);
                    }

                    for (int i = 0; i < table.Length; i++)
                    {
                        int j = 0;
                        for (; j <= i; j++)
                        {
                            pcell = new PdfPCell(new Phrase(new Chunk(this.table[i][j].ToString(), arial7)));
                            ptable.AddCell(pcell);
                        }
                        for (; j < table.Length; j++)
                        {
                            pcell = new PdfPCell(new Phrase(new Chunk("-", arial7)));
                            ptable.AddCell(pcell);
                        }
                    }
                }
                document.Add(new Paragraph("\n"));
                document.Add(ptable);
                document.Add(new Paragraph("Hasil integral: " + this.result));

            }
            catch (DocumentException de)
            {

            }
            catch (IOException ioe)
            {

            }
            document.Close();
        }
    }
}
